package com.autumn.util.excel;

import com.autumn.util.excel.column.AbstractColumn;
import com.autumn.util.excel.column.ColumnInfo;
import com.autumn.util.excel.exceptions.ExcelException;
import com.autumn.util.excel.export.AbstractExportInfo;
import com.autumn.util.excel.extensions.ColumnExtensions;
import com.autumn.util.excel.workbook.WorkbookExport;
import com.autumn.util.excel.workbook.WorkbookImportMap;
import com.autumn.util.excel.workbook.WorkbookImportObject;
import org.apache.poi.ss.usermodel.Workbook;

import java.io.InputStream;
import java.util.*;

/**
 * 工作薄信息
 */
public class WorkbookInfo {

	public WorkbookInfo() {
		initialize();
	}

	/**
	 * 工作表名称
	 */
	private String sheetName;

	/**
	 * 主标题
	 */
	private WorkbookHeader header;

	/**
	 * 子标题
	 */
	private WorkbookHeader childHeader;

	/**
	 * 获取列集合
	 */
	private List<AbstractColumn> columns;

	public void initialize() {
		if (header == null) {
			this.header = new WorkbookHeader();
			header.setShow(true);
			header.setRowHeight(50);
			header.setFontSize(18.0);
		}
		if (childHeader == null) {
			childHeader = new WorkbookHeader();
			childHeader.setShow(true);
			childHeader.setRowHeight(25);
		}
		if (columns == null) {
			this.columns = new ArrayList<>();
		}
	}

	/**
	 * 获取合并行数
	 *
	 * @return
	 */
	public int mergeRows() {
		return ColumnExtensions.mergeRows(getColumns());
	}

	/**
	 * 获取合并列数
	 *
	 * @return
	 */
	public int mergeCols() {
		return ColumnExtensions.mergeCols(getColumns());
	}

	/**
	 * 列排序
	 */
	public void orderColumns() {
		List<AbstractColumn> columns = getColumns();
		if (columns != null) {
			Collections.sort(columns, Comparator.comparingInt(AbstractColumn::getOrder));
			for (AbstractColumn column : columns) {
				column.orderColumns();
			}
		}
	}

	/**
	 * 检测
	 */
	public void check() {
		if (getColumns().size() == 0) {
			throw new ExcelException(this.getClass().getName() + " 至少需要一列以上。");
		}
		for (AbstractColumn column : columns) {
			column.check();
		}
	}

	/**
	 * 列信息列表
	 *
	 * @return
	 */
	public List<ColumnInfo> columnInfos() {
		List<ColumnInfo> items = new ArrayList<ColumnInfo>();
		Collections.sort(getColumns(), Comparator.comparingInt(AbstractColumn::getOrder));
		for (AbstractColumn column : getColumns()) {
			items.addAll(column.columnInfos());
		}
		return items;
	}

	/**
	 * 创建导出工作簿
	 *
	 * @param exportInfo
	 * @param isImportTemplate
	 * @return
	 */
	public <T> Workbook createExportWorkbook(AbstractExportInfo<T> exportInfo, boolean isImportTemplate) {
		WorkbookExport work = new WorkbookExport(this);
		return work.createWorkbook(exportInfo, isImportTemplate);
	}

	/**
	 * 导入项目集合
	 *
	 * @param imports   导入流
	 * @param sheetName 工作表名称,未指定则自动查找符合格式的首个表
	 * @return
	 */
	public <T> List<T> imports(InputStream imports, String sheetName, Class<T> clazz) {
		WorkbookImportObject<T> work = new WorkbookImportObject<T>(this, clazz);
		return work.imports(imports, sheetName);
	}

	/**
	 * 导入字典
	 *
	 * @param imports   导入流
	 * @param sheetName 工作表名称,未指定则自动查找符合格式的首个表
	 * @return
	 */
	public List<Map<String, Object>> importMap(InputStream imports, String sheetName) {
		WorkbookImportMap work = new WorkbookImportMap(this);
		return work.imports(imports, sheetName);
	}

	/**
	 * 导入字典
	 *
	 * @param imports        导入流
	 * @param sheetName      工作表名称,未指定则自动查找符合格式的首个表
	 * @param isInsitiveCase 字符比较器
	 * @return
	 */
	public List<Map<String, Object>> importMap(InputStream imports, String sheetName, boolean isInsitiveCase) {
		WorkbookImportMap work = new WorkbookImportMap(this, isInsitiveCase, Map.class);
		return work.imports(imports, sheetName);
	}

	public String getSheetName() {
		return sheetName;
	}

	public void setSheetName(String sheetName) {
		this.sheetName = sheetName;
	}

	public WorkbookHeader getHeader() {
		return header;
	}

	public void setHeader(WorkbookHeader header) {
		this.header = header;
	}

	public WorkbookHeader getChildHeader() {
		return childHeader;
	}

	public void setChildHeader(WorkbookHeader childHeader) {
		this.childHeader = childHeader;
	}

	public List<AbstractColumn> getColumns() {
		return columns;
	}

	public void setColumns(List<AbstractColumn> columns) {
		this.columns = columns;
	}
}
